<template>
    <div ref="threeRef"></div>
</template>

<script setup lang="ts">
import * as THREE from 'three'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

const threeRef = ref<HTMLDivElement>()
// 场景
const scene = new THREE.Scene()
// 相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
// 相机位置
camera.position.set(300, 100, -80)
// 相机视点
camera.lookAt(new THREE.Vector3(0, 0, 0))

// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
// 材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
// 创建网格
const cube = new THREE.Mesh(geometry, material)
// 添加网格到场景
// scene.add(cube)

// 创建环境光
const light = new THREE.AmbientLight(0xffffff, 0.8)
light.position.set(0, 0, 0)
// 添加环境光到场景
scene.add(light)

// 创建平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
// 设置平行光位置
directionalLight.position.set(150, 150, -150)
const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5)
// 添加平行光到场景
scene.add(directionalLight)
scene.add(directionalLightHelper)

// gltf模型加载器
const gltfLoader = new GLTFLoader()
// draco解码器
const dracoLoader = new DRACOLoader()
// 设置draco解码器路径
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/')
// 设置draco解码器
gltfLoader.setDRACOLoader(dracoLoader)

// 加载模型
gltfLoader.load('./model/lod0/modelHouse.gltf', (gltf) => {
    if (gltf.scene) {
        gltf.scene.rotateX(-Math.PI / 2)
        scene.add(gltf.scene)
    }
    gltf.scene.traverse((item) => {
        if (item.type === 'Mesh' && item.visible) {
            const geometry = (item as THREE.Mesh).geometry
            //获取边缘geometry
            const edgesGeometry = new THREE.EdgesGeometry(geometry)
            //获取线框geometry
            // const edgesGeometry = new THREE.WireframeGeometry(geometry);
            //创建线段材质
            const edgesMaterial = new THREE.LineBasicMaterial({ color: 0xffffff })
            //创建线段
            const edges = new THREE.LineSegments(edgesGeometry, edgesMaterial)
            // 更新建筑物世界转换矩阵
            item.updateWorldMatrix(true, true)
            edges.matrix.copy(item.matrixWorld)
            edges.matrix.decompose(edges.position, edges.quaternion, edges.scale)
            scene.add(edges)
        }
    })
})

// 渲染器
const renderer = new THREE.WebGLRenderer()
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight)

// 控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 启用阻尼
controls.enableDamping = true
// 阻尼惯性
controls.dampingFactor = 0.05

onMounted(() => {
    // 将渲染器添加到页面中
    threeRef.value?.appendChild(renderer.domElement)
    animate()
    window.addEventListener('resize', resize)
})
onUnmounted(() => {
    window.removeEventListener('resize', resize)
})

const animate = () => {
    // 动画
    requestAnimationFrame(animate)
    // 控制器更新
    controls.update()
    // 渲染
    renderer.render(scene, camera)
}
const resize = () => {
    // 更新摄像头
    camera.aspect = window.innerWidth / window.innerHeight
    // 更新摄像头的投影矩阵
    camera.updateProjectionMatrix()
    // 更新渲染器
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio)
}
</script>

<style lang="scss" scoped></style>
